package com.example.demo2.controller;

import com.example.demo2.dto.*;
import com.example.demo2.entity.Permission;
import com.example.demo2.entity.PermissionConnection;
import com.example.demo2.mapper.StudyMapper;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import jakarta.transaction.Transactional;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.text.PDFTextStripperByArea;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/training")
@CrossOrigin // 允许来自前端的请求
public class TrainingController {

    // 获取当前工作目录的File对象
    File userDir = new File(System.getProperty("user.dir"));

    // 获取父目录的File对象，即D:/idea/
    File parentDir = userDir.getParentFile();

    // 再次获取上一级目录的File对象，即D:/
    File grandParentDir = parentDir.getParentFile();

    // 现在grandParentDir指向D:/，我们想在D:/下创建file目录
    // 因此，我们创建一个新的File对象指向D:/file
    File fileDir = new File(grandParentDir, "file");

    // 将fileDir转换为绝对路径
    String ROOT_PATH = fileDir.getAbsolutePath();

    @Autowired
    private StudyMapper studyMapper;
    @Autowired
    private ParameterNamesModule parameterNamesModule;
    @Value("${certificate.base-path}")
    private String basePath;

    @Value("${certificate.base-url}")
    private String baseUrl;
    // 根据项目 ID 获取所有培训详情（培训记录、培训视频、考核试卷）
    @GetMapping("/getTrainingDetails")
    public TrainingDetailsDTO getTrainingDetails(@RequestParam("projectId") int projectId) {
        TrainingDetailsDTO trainingDetails = new TrainingDetailsDTO();

        // 获取培训记录
        List<TrainingRecordDTO> trainingRecords = studyMapper.getTrainingRecordsByProjectId(projectId);
        trainingDetails.setTrainingRecords(trainingRecords);

        // 打印获取到的培训记录
        System.out.println("培训记录: " + trainingRecords);

        // 获取培训视频
        List<ProgramDTO> trainingVideos = studyMapper.getTrainingVideosByProjectId(projectId);
        trainingDetails.setTrainingVideos(trainingVideos);

        // 打印获取到的培训视频
        System.out.println("培训视频: " + trainingVideos);

        // 获取考核试卷
        List<ProgramDTO> assessmentPapers = studyMapper.getAssessmentPapersByProjectId(projectId);
        trainingDetails.setAssessmentPapers(assessmentPapers);

        // 打印获取到的考核试卷
        System.out.println("考核试卷: " + assessmentPapers);

        // 打印完整的培训详情对象
        System.out.println("完整的培训详情: " + trainingDetails);

        return trainingDetails;
    }

    // 导出培训记录为 Excel
    @GetMapping("/exportTrainingRecords")
    public void exportTrainingRecords(@RequestParam("projectId") int projectId, HttpServletResponse response) {
        List<TrainingRecordDTO> records = studyMapper.getTrainingRecordsByProjectId(projectId);
        try (XSSFWorkbook workbook = new XSSFWorkbook()) {
            XSSFSheet sheet = workbook.createSheet("Training Records");

            // 创建表头
            XSSFRow headerRow = sheet.createRow(0);
            headerRow.createCell(0).setCellValue("证书 ID");
            headerRow.createCell(1).setCellValue("用户名");
            headerRow.createCell(2).setCellValue("证书发布时间");
            headerRow.createCell(3).setCellValue("证书类别");

            // 填充数据
            int rowIndex = 1;
            for (TrainingRecordDTO record : records) {
                XSSFRow row = sheet.createRow(rowIndex++);
                row.createCell(0).setCellValue(record.getPeId());
                row.createCell(1).setCellValue(record.getuName());
                row.createCell(2).setCellValue(record.getPmcTime().toString());
                row.createCell(3).setCellValue(record.getPeType());
            }

            // 设置响应头
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-Disposition", "attachment; filename=TrainingRecords.xlsx");

            // 输出 Excel 文件
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //上传视频

    private ResponseEntity<String> uploadFile(MultipartFile file, String fileType, int projectId, String pgName) {
        if (file.isEmpty()) {
            return ResponseEntity.badRequest().body("文件为空，请选择要上传的文件");
        }
        try {
            // 设置保存路径，确保文件保存在对外开放的目录
            String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
            File destFile = new File(ROOT_PATH + File.separator  + fileType +File.separator + fileName);

            // 创建目录，如果不存在则创建
            if (!destFile.getParentFile().exists()) {
                destFile.getParentFile().mkdirs();
            }

            // 保存文件
            file.transferTo(destFile);

            // 生成完整的文件 URL
            String fileUrl = "http://localhost:8081/files/" + fileType + "/" + fileName;

            // 根据fileType来选择调用不同的Mapper方法
            if ("videos".equals(fileType)) {
                studyMapper.uploadTrainingVideo(projectId, pgName, fileUrl);
            } else if ("images".equals(fileType)) {
                studyMapper.uploadExam(projectId, pgName, fileUrl);
            } else {
                return ResponseEntity.badRequest().body("不支持的文件类型");
            }

            return ResponseEntity.ok("文件上传成功：" + fileUrl);
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("文件上传失败: " + e.getMessage());
        }
    }


    @PostMapping("/uploadTrainingVideo")
    public ResponseEntity<String> uploadTrainingVideo(@RequestParam("projectId") int projectId,
                                                      @RequestParam("pgName") String pgName,
                                                      @RequestParam("file") MultipartFile file) {
        return uploadFile(file, "videos", projectId,pgName);
    }

    @PostMapping("/uploadTrainingImage")
    public ResponseEntity<String> uploadTrainingImage(@RequestParam("projectId") int projectId,
                                                      @RequestParam("pgName") String pgName,
                                                      @RequestParam("file") MultipartFile file) {
        return uploadFile(file, "images", projectId,pgName);
    }








    @DeleteMapping("/deleteTrainingVideo")
    public ResponseEntity<String> deleteTrainingVideo(@RequestParam("programId") int programId) {
        try {
            // 通过 programId 获取要删除的文件的 URL
            ProgramDTO program = studyMapper.getProgramById(programId);
            if (program == null || !"1".equals(program.getPgType())) { // 修改这里
                return ResponseEntity.badRequest().body("Invalid program ID or type");
            }

            // 删除本地文件
            String fileType = "videos";
            String filePath = ROOT_PATH + File.separator  + fileType + File.separator + program.getPgUrl().replace("http://localhost:8081/files/videos/", "");
            File file = new File(filePath);
            if (file.exists()) {
                boolean deleted = file.delete();
                if (!deleted) {
                    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to delete the file");
                }
            } else {
                return ResponseEntity.badRequest().body("File does not exist");
            }

            // 删除数据库中的记录
            studyMapper.deleteTrainingVideo(programId);

            return ResponseEntity.ok("Training video deleted successfully");

        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error occurred during file deletion: " + e.getMessage());
        }
    }



    @DeleteMapping("/deleteExam")
    public ResponseEntity<String> deleteExam(@RequestParam("programId") int programId) {
        try {
            // 通过 programId 获取要删除的文件的 URL
            ProgramDTO program = studyMapper.getProgramById(programId);
            if (program == null || !"2".equals(program.getPgType())) {
                return ResponseEntity.badRequest().body("Invalid program ID or type");
            }

            String fileType = "images";
            // 删除本地文件
            String filePath = ROOT_PATH + File.separator  + fileType +File.separator + program.getPgUrl().replace("http://localhost:8081/files/images/", "");
            File file = new File(filePath);
            if (file.exists()) {
                file.delete();
            }

            // 删除数据库中的记录
            studyMapper.deleteExam(programId);

            return ResponseEntity.ok("Exam deleted successfully");

        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Error occurred during file deletion: " + e.getMessage());
        }
    }



    // 根据项目 ID 获取学习记录
    @GetMapping("/getStudyRecords")
    public List<StudyRecordDTO> getStudyRecords(@RequestParam("projectId") int projectId) {
        return studyMapper.getStudyRecordsByProjectId(projectId);
    }

    // 导出学习记录为 Excel
    @GetMapping("/exportStudyRecords")
    public ResponseEntity<byte[]> exportStudyRecords(@RequestParam("projectId") int projectId) {
        List<StudyRecordDTO> records = studyMapper.getStudyRecordsByProjectId(projectId);
        try (XSSFWorkbook workbook = new XSSFWorkbook()) {
            XSSFSheet sheet = workbook.createSheet("Study Records");

            // 创建表头
            XSSFRow headerRow = sheet.createRow(0);
            headerRow.createCell(0).setCellValue("学习表ID");
            headerRow.createCell(1).setCellValue("用户名");
            headerRow.createCell(2).setCellValue("提交时间");
            headerRow.createCell(3).setCellValue("审核时间");
            headerRow.createCell(4).setCellValue("审核状态");

            // 填充数据
            int rowIndex = 1;
            for (StudyRecordDTO record : records) {
                XSSFRow row = sheet.createRow(rowIndex++);
                row.createCell(0).setCellValue(record.getsId());
                row.createCell(1).setCellValue(record.getuName());
                row.createCell(2).setCellValue(record.getStartTime() != null ? record.getStartTime().toString() : "");
                row.createCell(3).setCellValue(record.getsRead() != null ? record.getsRead().toString() : "");
                row.createCell(4).setCellValue(record.getPass() == 1 ? "已通过" : "未通过"); // 转换为字符串状态
            }

            // 写入工作簿到字节数组
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            workbook.write(bos);
            byte[] excelBytes = bos.toByteArray();

            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
            headers.setContentDispositionFormData("attachment", "study_records.xlsx");

            return new ResponseEntity<>(excelBytes, headers, HttpStatus.OK);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    // 根据学习表 ID 获取 PaperUrl 和 VideoUrl
    @GetMapping("/getStudyResources")
    public ResponseEntity<StudyResourcesDTO> getStudyResources(@RequestParam("studyId") int studyId) {
        StudyResourcesDTO resources = studyMapper.getStudyResourcesById(studyId);
        if (resources == null) {
            //logger.error("无法找到 studyId: {} 的学习资源", studyId);
            return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
        }
        return ResponseEntity.ok(resources);
    }



    // 授权接口
    @Transactional
    @PostMapping("/addTextToCertificate")
    public ResponseEntity<String> addTextToCertificate(@RequestBody Map<String, Integer> params) {
        int sId = params.get("sId");
        //logger.info("Received addTextToCertificate request for sId: {}", sId);

        // 获取 Study 信息
        StudyInfoDTO study = studyMapper.getStudyInfoById(sId);
        if (study == null) {
            //logger.error("Study 信息不存在，sId: {}", sId);
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Study 信息不存在，sId: " + sId);
        }

        // 插入 Permission 表，初始 peurl 为 null
        Permission permission = new Permission();
        permission.setPeUrl(null); // 初始为 null
        permission.setPeType(1);
        try {
            studyMapper.insertPermission(permission);
            int peid = permission.getPeid();
            study.setPmID(String.valueOf(peid));
            //logger.info("Inserted Permission with peid: {}", peid);

            // 插入 PermissionConnect 表，初始 pmurl 为 null
            PermissionConnectionDTO permissionConnection = new PermissionConnectionDTO();
            permissionConnection.setPmcid(peid);
            permissionConnection.setUid(study.getUid());
            permissionConnection.setPjid(study.getPjId());
            permissionConnection.setPmUrl(null); // 初始为 null
            permissionConnection.setPmType(1);
            studyMapper.insertPermissionConnect(permissionConnection);
            //logger.info("Inserted PermissionConnect with peid: {}", peid);
            // 更新 Study 表的 pmid
            try {
                String sRead = studyMapper.getsReadpmcTime(peid);
                studyMapper.updateStudyPmid(sId, peid);
                studyMapper.updateStudyPass(sId, 1);
                studyMapper.updateStudysRead(sId,sRead);
                //logger.info("Updated Study pmid for sId: {}", sId);
            } catch (Exception e) {
                //logger.error("更新 Study 表的 pmid 失败: {}", e.getMessage());
                throw new RuntimeException("更新 Study 表的 pmid 失败: " + e.getMessage());
            }
            // 生成 PDF 证书
            String newCertificatePath;
            try {
                newCertificatePath = generateAndSaveCertificate(study);
                //logger.info("Generated PDF certificate at: {}", newCertificatePath);
            } catch (Exception e) {
                //logger.error("PDF 生成失败: {}", e.getMessage());
                // 回滚事务
                throw new RuntimeException("PDF 生成失败: " + e.getMessage());
            }

            // 更新 Permission 表的 peurl
            try {
                //studyMapper.updatePermissionConnectUrl(peid, newCertificatePath);
                // 假设 updateCertificateUrl 只更新 Study 表
                // 需要新增方法来更新 Permission 表的 peurl
                studyMapper.updatePermissionUrl(peid, newCertificatePath);
                //logger.info("Updated Permission peurl for peid: {}", peid);
            } catch (Exception e) {
                //logger.error("更新 Permission 表的 peurl 失败: {}", e.getMessage());
                throw new RuntimeException("更新 Permission 表的 peurl 失败: " + e.getMessage());
            }

            // 更新 PermissionConnect 表的 pmurl
            try {
                studyMapper.updatePermissionConnectUrl(peid, newCertificatePath);
                //logger.info("Updated PermissionConnect pmurl for peid: {}", peid);
            } catch (Exception e) {
                //logger.error("更新 PermissionConnect 表的 pmurl 失败: {}", e.getMessage());
                throw new RuntimeException("更新 PermissionConnect 表的 pmurl 失败: " + e.getMessage());
            }



        } catch (Exception e) {
            //logger.error("授权流程失败: {}", e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("授权流程失败: " + e.getMessage());
        }

        //logger.info("成功为 sId: {} 生成并保存证书", sId);
        return ResponseEntity.ok("Text added to PDF successfully");
    }



    // 生成并保存 PDF 证书
    private String generateAndSaveCertificate(StudyInfoDTO study) throws Exception {
        String pmid = study.getPmID() ;
        String newCertificateFileName = "授权证书_" + pmid + ".pdf";
        String fileType = "pdfs";
        String newCertificatePath = ROOT_PATH + File.separator  + fileType +File.separator  + newCertificateFileName;

        File certificateTemplate = new File(ROOT_PATH + File.separator  + fileType +File.separator + "授权证书.pdf"); // 模板文件路径
        if (!certificateTemplate.exists()) {
            throw new IOException("Certificate template file does not exist at: " + certificateTemplate.getAbsolutePath());
        }

        try (PDDocument document = PDDocument.load(certificateTemplate)) {
            // 获取中文字体
            PDType0Font font;
            font = PDType0Font.load(document, new File("C:/Windows/Fonts/STSONG.TTF")); // 字体路径

            // 构建文本内容
            String text = String.format(
                    "证书ID:%s\n兹证明     %s      先生/女士：\n       于%s完成%s，\n%s，%s项目考核，\n获得该项目检测授权。\n       特发此证\n\n\n\n签发单位：名茜生物有限公司\n日期：%s",
                    pmid,
                    study.getuName() != null ? study.getuName() : "",
                    study.getsRead() != null ? study.getsRead().toString() : "",
                    study.getStaName() != null ? study.getStaName() : "",
                    study.getStaGb() != null ? study.getStaGb() : "",
                    study.getPjName() != null ? study.getPjName() : "",
                    study.getsRead() != null ? study.getsRead().toString() : ""
            );

            // 在 PDF 中添加新文本
            for (PDPage page : document.getPages()) {
                try (PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true)) {
                    contentStream.beginText();
                    contentStream.setFont(font, 22);
                    contentStream.newLineAtOffset(300, 380); // 根据需要调整位置
                    String[] lines = text.split("\n");
                    for (String line : lines) {
                        contentStream.showText(line);
                        contentStream.newLineAtOffset(0, -35); // 行间距调整
                    }
                    contentStream.endText();
                }
            }

            // 保存更新后的 PDF 文件
            document.save(newCertificatePath);
        } catch (IOException e) {
            //logger.error("处理 PDF 文件失败: {}", e.getMessage());
            throw new IOException("处理 PDF 文件失败: " + e.getMessage());
        }

        // 返回可访问的 URL
        return baseUrl + newCertificateFileName;
    }

    // 驳回审核接口
    @Transactional
    @PostMapping("/rejectAudit")
    public ResponseEntity<String> rejectAudit(@RequestBody Map<String, Object> params) {
        int sId = (int) params.get("sId");
        String reason = (String) params.get("reason");
        //logger.info("Received rejectAudit request for sId: {}, reason: {}", sId, reason);

        try {
            // 更新 Study 表的 pass 字段为 2
            studyMapper.updateStudyPass(sId, 2);
            // 可以在此处记录驳回理由到另一个表，视需求而定
        } catch (Exception e) {
            //logger.error("驳回审核失败: {}", e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("驳回审核失败: " + e.getMessage());
        }

        //logger.info("成功驳回审核，sId: {}", sId);
        return ResponseEntity.ok("Audit rejected successfully");
    }

}











